﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

namespace SiKuma.ScreenSystemLibrary
{
    public class InputMap
    {
        public struct Input
        {
            private Keys key;
            private Buttons button;
            private Triggers trigger;
            private MousePresses mousepresses;

            public void setKey(Keys k)
            {
                this.key = k;
            }

            public Keys getKey()
            {
                return this.key;
            }

            public void setButton(Buttons b)
            {
                this.button = b;
            }

            public Buttons getButton()
            {
                return this.button;
            }

            public void setTrigger(Triggers t)
            {
                this.trigger = t;
            }

            public Triggers getTrigger()
            {
                return this.trigger;
            }

            public void setMousePress(MousePresses m)
            {
                this.mousepresses = m;
            }

            public MousePresses getMousePress()
            {
                return this.mousepresses;
            }
        }

        private Dictionary<string, List<InputMap.Input>> keybinds;
        
        public InputMap()
        {
            this.keybinds = new Dictionary<string, List<InputMap.Input>>();
        }

        public void NewAction(string action, InputMap.Input input)
        {
            if (this.keybinds.ContainsKey(action))
            {
                this.keybinds[action].Add(input);
                return;
            }
            this.keybinds.Add(action, new List<InputMap.Input>(new InputMap.Input[]
			{
				input
			}));
        }
        
        public void NewAction(string action, Keys k)
        {
            InputMap.Input input = default(InputMap.Input);
            input.setKey(k);
            this.NewAction(action, input);
        }
        
        public void NewAction(string action, Buttons b)
        {
            InputMap.Input input = default(InputMap.Input);
            input.setButton(b);
            this.NewAction(action, input);
        }
        public void NewAction(string action, Triggers t)
        {
            if (t != Triggers.None)
            {
                InputMap.Input input = default(InputMap.Input);
                input.setTrigger(t);
                this.NewAction(action, input);
            }
        }
        
        public void NewAction(string action, MousePresses m)
        {
            if (m != MousePresses.None)
            {
                InputMap.Input input = default(InputMap.Input);
                input.setMousePress(m);
                this.NewAction(action, input);
            }
        }
        
        public List<InputMap.Input> GetKeybinds(string actionName)
        {
            return this.keybinds[actionName];
        }
        
        public Vector2 GetMousePosition()
        {
            return InputSystem.MousePosition();
        }
        
        public float GetTriggerValue(Triggers t)
        {
            if (t == Triggers.LeftTrigger)
            {
                return InputSystem.LeftTrigger();
            }
            if (t == Triggers.RightTrigger)
            {
                return InputSystem.RightTrigger();
            }
            return 0f;
        }
        
        public bool ActionPressed(string actionName)
        {
            if (this.keybinds.ContainsKey(actionName))
            {
                List<InputMap.Input> list = this.keybinds[actionName];
                foreach (InputMap.Input current in list)
                {
                    float triggerValue = this.GetTriggerValue(current.getTrigger());
                    if (InputSystem.IsPressedKey(current.getKey()) || InputSystem.IsPressedButton(current.getButton()) || InputSystem.IsPressedMouse(current.getMousePress()) || triggerValue > 0.2f)
                    {
                        return true;
                    }
                }
                return false;
            }
            return false;
        }
        
        public bool NewActionPress(string actionName)
        {
            if (this.keybinds.ContainsKey(actionName))
            {
                List<InputMap.Input> list = this.keybinds[actionName];
                foreach (InputMap.Input current in list)
                {
                    float triggerValue = this.GetTriggerValue(current.getTrigger());
                    if (InputSystem.IsNewKeyPress(current.getKey()) || InputSystem.IsNewButtonPress(current.getButton()) || InputSystem.IsNewMousePress(current.getMousePress()) || triggerValue > 0.2f)
                    {
                        return true;
                    }
                }
                return false;
            }
            return false;
        }
        
        public bool HeldAction(string actionName)
        {
            if (this.keybinds.ContainsKey(actionName))
            {
                List<InputMap.Input> list = this.keybinds[actionName];
                foreach (InputMap.Input current in list)
                {
                    float triggerValue = this.GetTriggerValue(current.getTrigger());
                    if (InputSystem.IsHeldKey(current.getKey()) || InputSystem.IsHeldButton(current.getButton()) || InputSystem.IsHeldMousePress(current.getMousePress()) || triggerValue > 0.2f)
                    {
                        return true;
                    }
                }
                return false;
            }
            return false;
        }
    }
}
